package com.hulk.dryad.admin.security.token;

import com.hulk.dryad.common.component.R;
import com.hulk.dryad.common.constant.SecurityConstants;
import com.hulk.dryad.common.util.WebUtils;
import com.hulk.dryad.admin.security.service.AdminUser;
import lombok.SneakyThrows;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * <p>
 *
 * @author kim
 * @date 2020/10/15
 */
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

	private TokenManager adminTokenManager;

	public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, AuthenticationFailureHandler failureHandler) {
		this.setAuthenticationManager(authenticationManager);
		this.adminTokenManager = tokenManager;
		this.setPostOnly(false);
		this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(SecurityConstants.OAUTH_TOKEN_URL));
		this.setAuthenticationFailureHandler(failureHandler);
	}

	@SneakyThrows
	@Override
	public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
			throws AuthenticationException {
		String username = this.obtainUsername(req);
		// 转字符集引发中文乱码
		// username =	new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
		String password = this.obtainPassword(req);
		if (username == null) {
			username = "";
		}
		if (password == null) {
			password = "";
		}

		username = username.trim();
		UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(username, password);
		return this.getAuthenticationManager().authenticate(authReq);
	}

	@Override
	protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
											Authentication authResult) throws IOException, ServletException {

		AdminUser user = (AdminUser) authResult.getPrincipal();
		String token = adminTokenManager.createToken(user.getUsername());
		LoginUserResp loginUserResp = new LoginUserResp();
		loginUserResp.setUsername(user.getUsername());
		loginUserResp.setAccess_token(token);
		loginUserResp.setUser_info(user);

		WebUtils.renderJson(response,R.ok(loginUserResp));
		super.successfulAuthentication(request, response, chain, authResult);
	}
	@Override
	protected void unsuccessfulAuthentication(HttpServletRequest request,
											  HttpServletResponse response, AuthenticationException failed)
			throws IOException, ServletException {
		WebUtils.renderJson(response,R.failed(failed.getMessage()));
		super.unsuccessfulAuthentication(request,response,  failed);
	}



}
